#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<string>
#include<cstring>
#define int long long int
#define lowbit(x) x & -x
const int N=1e5+10;
using namespace std;
inline int read() {
	char c = getchar();
	int x = 0, f = 1;
	while(c < '0' || c > '9') {
		if(c == '-') f = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x * f;
}
int n,m,p,a[N*4];
struct node {
	int date;
	int cheng;
	int jia;
} tree[N*4+10];
void pushup(int root) {
	tree[root].date=(tree[root<<1].date+tree[root<<1|1].date)%p;
}
void build(int root,int l,int r) {
	tree[root].cheng=1;
	if(l==r) {
		tree[root].date=a[l];
		return ;
	}
	int mid=(l+r)/2;
	build(root<<1,l,mid);
	build(root<<1|1,mid+1,r);
	pushup(root);
}
void pushdown(int x,int l,int r) {
	int ls=x<<1,rs=x<<1|1,mid=(l+r)>>1;
	tree[ls].date=(tree[ls].date*tree[x].cheng%p+tree[x].jia*(mid-l+1)%p)%p;
	tree[ls].cheng=(tree[ls].cheng*tree[x].cheng)%p;
	tree[ls].jia=(tree[ls].jia*tree[x].cheng+tree[x].jia)%p;
	tree[rs].date=(tree[rs].date*tree[x].cheng%p+tree[x].jia*(r-(mid+1)+1)%p)%p;
	tree[rs].cheng=(tree[rs].cheng*tree[x].cheng)%p;
	tree[rs].jia=(tree[rs].jia*tree[x].cheng+tree[x].jia)%p;
	tree[x].jia=0;
	tree[x].cheng=1;
	return;
}
void update_cheng(int root,int l,int r,int x,int y,int k) {
	if(r<x || l>y) return ;
	if(l>=x & r<=y) {
		tree[root].date=(tree[root].date*k)%p;
		tree[root].cheng=(tree[root].cheng*k)%p;
		tree[root].jia=(tree[root].jia*k)%p;
		return;
	}
	pushdown(root,l,r);
	int mid=(l+r)>>1;
	update_cheng(root<<1,l,mid,x,y,k);
	update_cheng(root<<1|1,mid+1,r,x,y,k);
	pushup(root);
}

int query(int root,int l,int r,int x,int y) {
	if(r<x || l>y) return 0;
	if(l>=x && r<=y) {
		return tree[root].date;
	}
	pushdown(root,l,r);
	int mid=(l+r)>>1;
	return (query(root<<1,l,mid,x,y)+query(root<<1|1,mid+1,r,x,y))%p;
}
signed main() {
	scanf("%lld %lld %lld",&n,&m,&p);
	for(int i=1; i<=4*n; i++) tree[i].cheng=1;
	for(int i=1; i<=n; i++) {
		scanf("%lld",&a[i]);
	}
	build(1,1,n);
	int opt,x,y,k;
	while(m--) {
		scanf("%lld",&opt);
		if(opt==1) {
			scanf("%lld %lld %lld",&x,&y,&k);
			update_cheng(1,1,n,x,y,k);
		}
		if(opt==3) {
			scanf("%lld %lld",&x,&y);
			cout<<query(1,1,n,x,y)%p<<endl;
		}
	}
	return 0;
}
